#include "ConvSap2Esp.hpp"

namespace cc 
{
	ConvSap2Esp::ConvSap2Esp(CoCStr_t in_path, CoCStr_t out_path, CoCStr_t modo) :
		m_raw(NULL),
		m_in_path(in_path),
		m_out_path(out_path),
		m_file_size(0),
		m_modo(modo)
	{
	}

	bool ConvSap2Esp::Conv(void)
	{
		if (load(m_in_path, m_raw, m_file_size) == false) return false;
		bool is_imp = false;
		UInt_t pos_ini = 0, prev_i = 0, next_i = 0;
		std::vector<UInt_t> pos_puntos;
		std::vector<UInt_t> pos_comas;
		char imp_aux[50];
		for(UInt_t i = 0; i < m_file_size; i++)
		{
			if (i > 0) prev_i = i - 1;
			if (i+1 < m_file_size) next_i = i + 1;

			if (isdigit(m_raw[i]) && is_imp == false) // EMPIEZA UN NUMERO
			{
				is_imp = true;
				pos_ini = i;
			}

			// NO ES NI : NUMERO, NEGATIVO, ESPACIO, PUNTO, COMA
			else if (!isdigit(m_raw[i]) && m_raw[i] != '-' && !isspace(m_raw[i]) 
						&& m_raw[i] != '.' && m_raw[i] != ',' && is_imp == true)
			{
				pos_puntos.clear();
				pos_comas.clear();
				is_imp = false;
				pos_ini = 0;
			}

			else if ( 
						(isdigit(m_raw[prev_i]) && isspace(m_raw[i]) && is_imp == true) // NUMERO_ESPACIO
						||
						(isdigit(m_raw[i]) && i == m_file_size - 1 && is_imp == true)   // ES NUMERO Y EL ULTIMO CARACTER
					)
			{
				if (std::string(m_modo).compare(cc::args::mc_parm_sep) == 0)
				{
					for(std::vector<UInt_t>::iterator it = pos_puntos.begin(); it != pos_puntos.end(); it++)
						m_raw[*it] = ',';

					for(std::vector<UInt_t>::iterator it = pos_comas.begin(); it != pos_comas.end(); it++)
						m_raw[*it] = '.';
				}
				pos_puntos.clear();
				pos_comas.clear();
				is_imp = false;
				pos_ini = 0;
			}

			else if (isspace(m_raw[prev_i]) && isdigit(m_raw[i]) && is_imp == true) // ESPACIO_NUMERO
			{
				is_imp = true;
				pos_ini = i;
			}

			else if ( 
						(m_raw[i] == '-' && isspace(m_raw[next_i]) && is_imp == true) // NEGATIVO_ESPACIO
						||
						(m_raw[i] == '-' && i == m_file_size - 1 && is_imp == true)   // NEGATIVO Y ULTIMO CARACTER
					)
			{
				if (std::string(m_modo).compare(cc::args::mc_parm_neg) == 0)
				{
					memset(imp_aux, 0 , 50);
					strncpy(imp_aux, m_raw+pos_ini, i - pos_ini);
					m_raw[pos_ini] = '-';
					strncpy(m_raw+pos_ini+1, imp_aux, i - pos_ini);					
				}
				else if (std::string(m_modo).compare(cc::args::mc_parm_sep) == 0)
				{
					for(std::vector<UInt_t>::iterator it = pos_puntos.begin(); it != pos_puntos.end(); it++)
						m_raw[*it] = ',';

					for(std::vector<UInt_t>::iterator it = pos_comas.begin(); it != pos_comas.end(); it++)
						m_raw[*it] = '.';
				}
				pos_puntos.clear();
				pos_comas.clear();
				is_imp = false;
				pos_ini = 0;
			}

			else if (m_raw[i] == '.' && is_imp == true)
			{
				pos_puntos.push_back(i);
			}

			else if (m_raw[i] == ',' && is_imp == true)
			{
				pos_comas.push_back(i);
			}

			else continue;
		}

		return true;
	}

	ConvSap2Esp::~ConvSap2Esp(void)
	{
		if (m_raw != NULL)
			delete[] m_raw;
	}

	bool ConvSap2Esp::Save()
	{
		std::ofstream os( m_out_path );
        if (os.is_open())
        {
			os.write(m_raw, m_file_size);
			os.close();
		} else return false;

		return true;
	}
	bool ConvSap2Esp::load(CoCStr_t in_path, CStr_t& raw, UInt_t& file_size)
	{
		std::ifstream is( in_path );
        if (is.is_open())
        {            
			is.seekg(0, std::ios::beg);
			is.seekg( 0, std::ios::end );
			long fileSize = is.tellg();
			is.seekg( 0, std::ios::beg );
			raw = new char[fileSize+1];
			memset(raw, 0, fileSize+1);
			file_size = fileSize;
			is.read( raw, fileSize );
			is.close();
		} 
		else
		{
			std::cerr << "Se ha producido un error al cargar el fichero de entrada." << std::endl;
			return false;
		}

		return true;
	}
}
